/**
 * TetisDB
 *
 * Classe responsavel por efetuar buscas no snapshot
 */

package br.com.tetisdb.query;

import br.com.tetisdb.exception.TetisAttributeNotFoundException;
import br.com.tetisdb.lang.TetisHashMap;
import br.com.tetisdb.lang.TetisObject;
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;

public class TQuery extends TetisObject implements TetisQuery {
    //classe a ser buscada
    private Class clazz;
    //atributos dessa class
    private Field[] attrs;
    //lista de atributos de constrain
    private LinkedList listaAtributos;
    //objeto que efetua a busca
    private Finder finder;
    
    /**
     * Construtor padrao
     *
     * @param clazz Classe a ser procurada
     * @param snap SnapShot onde a busca sera feita
     */
    public TQuery(Class clazz, TetisHashMap<String, Object> snap) {
        tetisLogger.debug("Criando TQuery para a classe: "+clazz.getName());
        this.clazz = clazz;
        tetisLogger.debug("Listando atributos para busca");
        attrs = clazz.getDeclaredFields();
        listaAtributos = new LinkedList();
        tetisLogger.debug("Criando Finder...");
        finder = new Finder(snap);
        tetisLogger.debug("Finder criado");
    }
    
    /**
     * Adiocioa um atributo para a busca
     *
     * @param attributeName Nome do atributo a ser questionado
     * @return Attribute Atributo para a busca.
     */
    public Attribute addAttribute(String attributeName) throws TetisAttributeNotFoundException {
        tetisLogger.debug("Adicionando atributo: "+attributeName+" na busca");
        if(existAttribute(attributeName)) {
            Attribute at = new Attribute(attributeName);
            getListaAtributos().add(at);
            return at;
        } else {
            throw new TetisAttributeNotFoundException("Atributo "+attributeName+" nao encontrado!");
        }
    }
    
    private boolean existAttribute(String name) {
        for(int i=0; i<attrs.length; i++) {
            Field att = (Field) attrs[i];
            
            if(att != null) {
                if(att.getName().equalsIgnoreCase(name)) {
                    return true;
                }
            }
        }
        
        return false;
    }
    
    /**
     * Efetua a busca.
     *
     * @return Retorna uma lista com os objetos encontrados.
     */   
    public List execute() throws Exception {
        return finder.find(this);
    }

    protected LinkedList getListaAtributos() {
        return listaAtributos;
    }

    protected Class getClazz() {
        return clazz;
    }
}
